home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / groff108.lha / groff-1.08 / libgroff / searchpath.cc < prev    next >
C/C++ Source or Header  |  1992-08-03  |  3KB  |  118 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.com)
  4.  
  5. This file is part of groff.
  6.  
  7. groff is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 2, or (at your option) any later
  10. version.
  11.  
  12. groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License along
  18. with groff; see the file COPYING.  If not, write to the Free Software
  19. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <assert.h>
  25.  
  26. #include "lib.h"
  27. #include "searchpath.h"
  28.  
  29. search_path::search_path(const char *envvar, const char *standard)
  30. {
  31.   char *e = envvar ? getenv(envvar) : 0;
  32.   if (e && standard) {
  33.     dirs = new char[strlen(e) + strlen(standard) + 2];
  34.     strcpy(dirs, e);
  35.     strcat(dirs, ":");
  36.     strcat(dirs, standard);
  37.   }
  38.   else
  39.     dirs = strsave(e ? e : standard);
  40.   init_len = dirs ? strlen(dirs) : 0;
  41. }
  42.  
  43. search_path::~search_path()
  44. {
  45.   if (dirs)
  46.     a_delete dirs;
  47. }
  48.  
  49. void search_path::command_line_dir(const char *s)
  50. {
  51.   if (!dirs)
  52.     dirs = strsave(s);
  53.   else {
  54.     char *old = dirs;
  55.     unsigned old_len = strlen(old);
  56.     unsigned slen = strlen(s);
  57.     dirs = new char[old_len + 1 + slen + 1];
  58.     memcpy(dirs, old, old_len - init_len);
  59.     char *p = dirs;
  60.     p += old_len - init_len;
  61.     if (init_len == 0)
  62.       *p++ = ':';
  63.     memcpy(p, s, slen);
  64.     p += slen;
  65.     if (init_len > 0) {
  66.       *p++ = ':';
  67.       memcpy(p, old + old_len - init_len, init_len);
  68.       p += init_len;
  69.     }
  70.     *p++ = '\0';
  71.     a_delete old;
  72.   }
  73. }
  74.  
  75. FILE *search_path::open_file(const char *name, char **pathp)
  76. {
  77.   assert(name != 0);
  78.   if (*name == '/' || dirs == 0 || *dirs == '\0') {
  79.     FILE *fp = fopen(name, "r");
  80.     if (fp) {
  81.       if (pathp)
  82.     *pathp = strsave(name);
  83.       return fp;
  84.     }
  85.     else
  86.       return 0;
  87.   }
  88.   unsigned namelen = strlen(name);
  89.   char *p = dirs;
  90.   for (;;) {
  91.     char *end = strchr(p, ':');
  92.     if (!end)
  93.       end = strchr(p, '\0');
  94.     int need_slash = end > p && end[-1] != '/';
  95.     char *path = new char[(end - p) + need_slash + namelen + 1];
  96.     memcpy(path, p, end - p);
  97.     if (need_slash)
  98.       path[end - p] = '/';
  99.     strcpy(path + (end - p) + need_slash, name);
  100. #if 0
  101.     fprintf(stderr, "trying `%s'\n", path);
  102. #endif
  103.     FILE *fp = fopen(path, "r");
  104.     if (fp) {
  105.       if (pathp)
  106.     *pathp = path;
  107.       else
  108.     a_delete path;
  109.       return fp;
  110.     }
  111.     a_delete path;
  112.     if (*end == '\0')
  113.       break;
  114.     p = end + 1;
  115.   }
  116.   return 0;
  117. }
  118.